﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once
#include "GcmpRenderingInterface.h"
#include "ElementId.h"
#include "Vector3d.h"
#include "Vector2d.h"

namespace gcmp
{
    enum class DiscreteEpsilonType;
    class IDocument;
    class IModelView;
    class IGraphicsBRepBody;

    /// \brief 网格离散选项设置
    class GCMP_RENDERING_INTERFACE_EXPORT IMeshDiscretizeOptions
    {
    public:
        virtual ~IMeshDiscretizeOptions();

        /// \brief 获取网格离散选项
        static IMeshDiscretizeOptions* Get();

        /// \brief 设置网格离散精度
        /// \param distanceEpsilon  距离精度，弓高大于此值将继续细分，默认50,越小离散精度越高，越大离散精度越低
        /// \param angleEpsilon     角度精度(弧度)，法向锥半角大于此值将继续细分，默认0.3490658503988（20度）
        /// \return 
        virtual void SetMeshDiscretizePrecision(double distanceEpsilon, double angleEpsilon) = 0;

        /// \brief 获取网格离散精度
        /// \param distanceEpsilon
        /// \param angleEpsilon
        /// \return 
        virtual void GetMeshDiscretizePrecision(double &distanceEpsilon, double &angleEpsilon) const = 0;

        /// \brief 设置是否使用Delaunay(狄洛尼)三角剖分算法，默认为false
        /// \param isUseDelaunay  是否使用Delaunay算法
        /// \return
        /// \note 开启后不保证一直离散要求，即重合的两个圆面，离散出来的顶点不一定重合；
        ///       对复杂的面（多个洞或边很多）性能会提升很多 
        virtual void SetIsUseDelaunayTriangulation(bool isUseDelaunay) = 0;

        /// \brief  是否使用Delaunay(狄洛尼)三角剖分算法
        /// \return  使用Delaunay(狄洛尼)三角剖分算法返回true,否则返回false
        virtual bool IsUseDelaunayTriangulation() const = 0;

        /// \brief 是否缓存文档中所有Brep体的平面的离散数据
        /// \return bool 是返回true，不是返回false
        virtual bool IsSavePlanarBrepFaceDiscretizedData() const = 0;

        /// \brief 设置是否缓存文档中所有Brep体的平面离散数据
        /// \
        /// 默认缓存所有Brep体的平面和曲面的离散数据进行复用，以减少离散次数，提升修改构件样式或构件材质等操作的性能。
        /// 但是当文档中的面的数量极大时，缓存可能会引起内存占用过高、性能下降等问题。用户可通过此接口设置不缓存Brep体的平面的离散数据。
        /// \param isSavePlanesDiscretizedData 是否缓存
        virtual void SetIsSavePlanarBrepFaceDiscretizedData(bool isSavePlanarBrepFaceDiscretizedData) = 0;

        /// \brief 离散后的UV坐标的后处理回调方法
        /// \param pDoc     当前文档
        /// \param id       当前离散的Element的Id
        /// \param pBody    当前离散的体
        /// \param faceTrianglesNum 体中各个面的三角面片数
        /// \param vertexList 离散后的顶点数据
        /// \param normalList 离散后的法线数据
        /// \param uvList     离散后的uv数据
        typedef std::function<void(const IDocument* pDoc, ElementId id, const IGraphicsBRepBody* pBody
            , const std::vector<int>& faceTrianglesNum, const std::vector<Vector3d>& vertexList
            , const std::vector<Vector3d>& normalList, std::vector<Vector2d>& uvList)> UVReprocessCallback;

        /// \brief 设置离散后的UV坐标的后处理回调方法
        /// \param callbackFunction 回调方法
        virtual void SetUVReprocessCallback(UVReprocessCallback callbackFunction) = 0;

        virtual UVReprocessCallback GetUVReprocessCallback() = 0;

        /// \brief 设置所有BRepBody几何离散的容差给定方式
        /// \param dType 几何离散的容差给定方式
        virtual void SetDiscreteEpsilonType(DiscreteEpsilonType deType) = 0;

        /// \brief 获取所有BRepBody几何离散的容差给定方式
        /// \return 返回几何离散的容差给定方式
        virtual DiscreteEpsilonType GetDiscreteEpsilonType() const = 0;
    };
}

